#ifndef RING_POLY_H
#define RING_POLY_H
#include <vector>
#include <cstdint>
#include <stdexcept>
#include "utils.h"
/* *
 * @class Poly
 * @brief 多项式类，表示一个多项式及其系数。
 *
 * `Poly` 类表示一个多项式，其中的系数存储在一个二维向量中。每个多项式的系数可以是不同模数下的整数。
 */
class Poly {
public:
    std::vector<std::vector<uint64_t>> Coeffs;
    bool isNTT = false;

    Poly();
    Poly(uint64_t N, uint64_t nbModuli);
    // 拷贝构造函数
    Poly(const Poly &other) = default;
    Poly &operator = (const Poly &other) = default;
    // 移动构造函数
    Poly(Poly &&other) = delete;
    Poly &operator = (Poly &&other) = delete;
    ~Poly();
    int GetDegree() const;
    void Zero();
    Poly *CopyNew() const;
    void Copy(Poly *p1);
    int Level();
    void CopyValues(Poly *p1);
};
/* *
 * @class PolyQP
 * @brief 存储Q基和P基的多项式。
 *
 * `PolyQP` 类存储了Q基和P基的两个多项式，分别表示加密过程中的Q基和P基部分。
 */
class PolyQP {
public:
    Poly *Q;
    Poly *P;

    PolyQP() {}
    PolyQP(Poly *Q, Poly *P);
    // 拷贝构造函数
    PolyQP(const PolyQP &other) = default;
    PolyQP &operator = (const PolyQP &other) = default;
    // 移动构造函数
    PolyQP(PolyQP &&other) = delete;
    PolyQP &operator = (PolyQP &&other) = delete;
};

Poly *NewPoly(uint64_t N, uint64_t nbModuli);
void CopyValues(Poly *p0, Poly *p1);
void CopyValuesLvl(int level, Poly *p0, Poly *p1);
void MapSmallDimensionToLargerDimensionNTT(Poly *polSmall, Poly *polLarge);

#endif // RING_POLY_H